package com.accelstack.cmp.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

/**
 * Token认证过滤器
 * 
 * 使用Spring Security标准的过滤器模式
 * 从请求头 x-auth-token 中提取Token并验证
 * 
 * 工作流程：
 * 1. 从请求头获取Token
 * 2. 验证Token有效性（查询Redis）
 * 3. 创建Authentication对象
 * 4. 设置到SecurityContext
 * 5. 自动刷新Token有效期
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TokenAuthenticationFilter extends OncePerRequestFilter {
    
    private final TokenManager tokenManager;
    
    @Value("${app.token.header:x-auth-token}")
    private String tokenHeader;
    
    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            @NonNull FilterChain filterChain) throws ServletException, IOException {
        
        try {
            String token = resolveToken(request);
            
            if (token != null && tokenManager.validateToken(token)) {
                String username = tokenManager.getUsernameFromToken(token);
                
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    log.debug("Token验证成功 - 用户: {}", username);
                    
                    // 创建认证对象
                    UsernamePasswordAuthenticationToken authentication = 
                        new UsernamePasswordAuthenticationToken(
                            username,
                            null,
                            Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))
                        );
                    
                    // 设置详细信息
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    
                    // 设置认证信息到SecurityContext
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    
                    // 自动刷新Token有效期（活跃用户Token自动延长）
                    tokenManager.refreshToken(token);
                }
            } else if (token != null) {
                log.debug("Token无效或已过期");
            }
        } catch (Exception e) {
            log.error("Token认证过程发生异常: {}", e.getMessage());
            // 清除可能存在的认证信息
            SecurityContextHolder.clearContext();
        }
        
        filterChain.doFilter(request, response);
    }
    
    /**
     * 从请求中解析Token
     * 支持从Header中获取
     */
    private String resolveToken(HttpServletRequest request) {
        // 从Header获取
        String headerToken = request.getHeader(tokenHeader);
        if (StringUtils.hasText(headerToken)) {
            return headerToken;
        }
        
        return null;
    }
}
